/**
 * Encryption manager
 *
 */

#ifndef	INCOGNITO_ENCMNGR_H
#define	INCOGNITO_ENCMNGR_H

#include "incognito_proto.h"
#include "keymngr.h"
#include <chord_types.h>

class incognito_impl;


// FIXME: Obsolete. Result of decryption
enum decryptres
{
	INCOGNITO_DECRYPT_OK		= 0,
	INCOGNITO_DECRYPT_NO_KEY	= 1,
	INCOGNITO_DECRYPT_XDR_FAILED	= 2,
};

//#include "incognito.h"

// FIXME: Obsolete. Callback typedefs
typedef callback<void,incognito_store_arg,decryptres>::ptr cbdecrypt;

// This class is used to encrypt and decrypt messages. keymngr is used to establish keys between nodes.
class encmngr:public virtual refcount
{
		class encparam
		{
			public:
				encparam():send_seq(random()) {}
			//protected:
				unsigned int send_seq;	// Sequence number for next packet
		};
		typedef std::map<chordID,encparam> encmap;
	public:
		enum encrypt_res
		{
			INCOGNITO_EM_ENCRYPT_OK			= 0,
			INCOGNITO_EM_ENCRYPT_NO_KEY		= 1,
			INCOGNITO_EM_ENCRYPT_REQUEST_TOO_BIG	= 2,
		};
		enum decrypt_res
		{
			INCOGNITO_EM_DECRYPT_OK			= 0,
			INCOGNITO_EM_DECRYPT_NO_KEY		= 1,
			INCOGNITO_EM_DECRYPT_XDR_FAILED		= 2,
		};

		typedef callback<void, ptr<incognito_encrypted_request>, encrypt_res>::ptr cb_encrypt;
		typedef callback<void, ptr<incognito_raw_request>, decrypt_res>::ptr cb_decrypt;

		encmngr(ptr<incognito_impl> ic,ptr<keymngr> keymngr):_ic(ic),_keymngr(keymngr) {}

		// Print statistics about keys. FIXME: To be implemented or removed.
		void print_stats();

		// Encrypts raw message (raw_msg) and calls cb(encrypted_msg)
		void encrypt(chord_node target, ptr<incognito_raw_request> raw_msg, cb_encrypt cb);
		// Encrypts raw message (raw_msg) and calls cb(encrypted_msg) - don't establish new key if key doesn't exists yet
		void encrypt(chordID target, ptr<incognito_raw_request> raw_msg, cb_encrypt cb);
		// Decrypts encrypted message (enc_msg) and calls cb(raw_msg)
		void decrypt(ptr<incognito_encrypted_request> enc_msg, cb_decrypt cb);
	protected:
		// Callback for get_key call in encrypt
		void encrypt_get_key_cb(chordID target, ptr<incognito_raw_request> raw_msg, cb_encrypt cb, bigint k, getkeyres res);
		// Calboack for get_key call in decrypt
		void decrypt2_get_key_cb(ptr<incognito_encrypted_request> enc_msg, cb_decrypt cb, bigint k, getkeyres res);
	public:
		// FIXME: Obsolete. Encrypt store request req and send to node n
		void encrypt_and_send_store(chord_node &n,ptr<incognito_store_arg> req);
		// FIXME: Obsolete. Decrypt store request
		void decrypt(ptr<incognito_enc_store_arg> arg, cbdecrypt cb);
	protected:
		// FIXME: Obsolete. Calback for get_key call in encrypt_and_send_store
		void encrypt_and_send_store_get_key_cb(chord_node n,ptr<incognito_store_arg> req, bigint k, getkeyres res);
		// FIXME: Obsolete. Calback for get_key call in decrypt
		void decrypt_get_key_cb(ptr<incognito_enc_store_arg> arg, cbdecrypt cb, bigint k, getkeyres res);
		
	

	private:
		encmngr() {}
	protected:
		encmap			_encmap;
		ptr<incognito_impl>	_ic;
		ptr<keymngr>		_keymngr;
		
	
};

#endif	/* INCOGNITO_ENCMNGR_H*/
